#include "analysis.h"
#include "def.h"
#include "ourhdr.h"

static int OpPriority[MAX_OP_NUM] = {0};
// substrDes:the string to be replaced
// substrSrc:the string to replace the original string
// reture value: 0 Success
//		 1 Fail
int replaceStr(char* str,char* substrDes,char* substrSrc)
{
	char* buf;
	char* p;
	if ((strlen(str) == 0) || 
		(strlen(substrDes) == 0) || 
		(strlen(substrSrc) == 0)) return 1;
	while ((p=strstr(str,substrDes)) != 0)
	{
		if (strlen(substrDes) == strlen(substrSrc))
		{
			memcpy(p,substrSrc,strlen(substrSrc));
			continue;
		}
		else
		{
			buf = (char*)malloc(strlen(str)+1);
			strcpy(buf,p+strlen(substrDes));
			strcpy(p,substrSrc);
			strcat(p,buf);
			free(buf);
		}
	}
	return 0;
}

int InitOpList()
{
	memset(OpPriority,0,MAX_OP_NUM);	
	OpPriority['+'] = 4;
	OpPriority['-'] = 4; 
	OpPriority['*'] = 5;
 	OpPriority['/'] = 5;
	OpPriority['%'] = 5;
	OpPriority['('] = 8;
	OpPriority[')'] = 8;
	OpPriority['A'] = 8;
	OpPriority['B'] = 8;
	OpPriority['C'] = 8;
	OpPriority['D'] = 8;
	OpPriority['E'] = 8;
	OpPriority['F'] = 8;
	OpPriority['G'] = 8;
	OpPriority[','] = 1;
	return 0;
}

int AnalizeStr(char* expression,char* suffixExpression,char* opStack,double num[],int* n)
{
	replaceStr(expression,"sin","A");
	replaceStr(expression,"cos","B");
	replaceStr(expression,"ln","C");
	replaceStr(expression,"exp","D");
	replaceStr(expression,"sqrt","E");
	replaceStr(expression,"power","F");
	replaceStr(expression,"fabs","G");
	replaceStr(expression,"pi","3.1415926535");
	replaceStr(expression,"e","2.718281828");
	opStack[0] = 0;	// opStack[0] is the top of the stack
	InitOpList();
	CreateSuffixExpression(expression,suffixExpression,opStack,num,n);
}

int CreateSuffixExpression (char* strInfixExpression,char* strSuffixExpression,char* opStack,double num[],int* n)
{
 	char* p1;
	char* p2;
	double dResult;
	p1 = strInfixExpression;
	p2 = p1;
	while (*p1 != 0)
	{
		if (OpPriority[*p1] != 0)	
		{
			//*p1 is a Operator, not a num
			switch(*p1)
			{
			case ',':
				p1++;
				continue;
			case '(':
				opStack[0]++;
				opStack[opStack[0]] = *p1;
				break;
			case ')':
				while ((opStack[opStack[0]] != '(') && (opStack[0] != 0))
				{
					//strcat(strSuffixExpression,opStack[opStack[0]]);
					strSuffixExpression[strlen(strSuffixExpression)] = opStack[opStack[0]];
					strSuffixExpression[strlen(strSuffixExpression)+1] = 0;
					opStack[0]--;
				}
				if (opStack[opStack[0]] == '(')
				{
					opStack[opStack[0]] = 0;
					opStack[0]--;
				}
				if ((opStack[opStack[0]]>='A') && opStack[opStack[0]]<='G')
				{
					strSuffixExpression[strlen(strSuffixExpression)] = opStack[opStack[0]];
					strSuffixExpression[strlen(strSuffixExpression)+1] = 0;
					opStack[0]--;
				}
				break;
			default: 
				if (opStack[opStack[0]] == '(')
				{
					opStack[0]++;
					opStack[opStack[0]] = *p1;
				}
				else
				if (OpPriority[*p1]>OpPriority[opStack[opStack[0]]])
				{
					opStack[0]++;
					opStack[opStack[0]] = *p1;
				}
				else
				{
					strSuffixExpression[strlen(strSuffixExpression)] = opStack[opStack[0]];
					strSuffixExpression[strlen(strSuffixExpression)+1] = 0;
					opStack[opStack[0]] = *p1;
				}
			}
			p1++;
			
		}
		else
		{
			//*p1 is a num, not a Operator
			p2 = p1;
			while (((*p2)>='0') && ((*p2)<='9') || ((*p2) == '.'))
				p2++;
			//int nLength;
			//nLength = p2 - p1;
			//char buf[MAXLINE];
			//memcpy(buf,p1,nLength);
			//buf[nLength] = '\0';
			char* endptr;
			char buf[MAXLINE];
			strcpy(buf,p1);
			dResult = strtod(buf,&endptr);
			if (buf == endptr)
			{
				return 1;
			}
			else
			{
				(*n)++;
				num[*n] = dResult;
				strcat(strSuffixExpression,"n");
				p1 = p2;
			}
					
		}
	}
	while (opStack[0] != 0)
	{
		strSuffixExpression[strlen(strSuffixExpression)] = opStack[opStack[0]];
		opStack[0]--;
	}
	return 0;
}

